package router

import (
	"errors"
	"iris-wms/apps/admin/web/dto/din"
	"iris-wms/apps/admin/web/dto/dout"
	"iris-wms/apps/admin/web/service"
	"iris-wms/common/model"
	"iris-wms/common/pkg/icasbin"
	"iris-wms/common/tools"
	"iris-wms/common/tools/consts"
	"iris-wms/common/tools/result"

	"github.com/kataras/iris/v12"
	"gorm.io/gorm"
)

func NewAdminUserRoute() *adminUserRoute {
	return &adminUserRoute{}
}

type adminUserRoute struct{}

func (r *adminUserRoute) Login(ctx iris.Context, service_ service.AdminUserService) {
	// TODO 同时登陆一个账号，将已登陆的用户挤下线
	in := new(din.AdminUserLoginForm)
	if err := ctx.ReadJSON(&in); err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}
	ctx.Application().GetRoutesReadOnly()

	mUser, err := service_.GetByUsername(in.Username)
	if err != nil {
		if errors.Is(gorm.ErrRecordNotFound, err) {
			ctx.Values().Set(consts.INNER_CODE_KEY, result.Code_Username_Error)
			ctx.StopWithPlainError(iris.StatusBadRequest, err)
			return
		}
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	if mUser.Enable != 1 {
		ctx.Values().Set(consts.INNER_CODE_KEY, result.Code_User_Disabled)
		ctx.StopWithStatus(iris.StatusUnauthorized)
		return
	}

	ckPassword := tools.CheckPassword(mUser.Password, in.Password)
	if !ckPassword {
		ctx.Values().Set(consts.INNER_CODE_KEY, result.Code_Password_Error)
		ctx.StopWithStatus(iris.StatusBadRequest)
		return
	}

	token, err := tools.GenerateToken[*model.AdminUser](mUser)
	if err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}

	result.OKData(ctx, iris.Map{"token": token})
}

func (r *adminUserRoute) GetUserInfo(ctx iris.Context, service_ service.AdminUserService) {
	mUser, err := service_.GetById(ctx.Values().GetUintDefault(consts.UID, 0))
	if err != nil {
		if errors.Is(gorm.ErrRecordNotFound, err) {
			ctx.StopWithPlainError(iris.StatusBadRequest, err)
			return
		}
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OKData(ctx, mUser)
}

func (r *adminUserRoute) Logout(ctx iris.Context) {
	// TODO 清除 redis
	ctx.Values().Reset()
	result.OK(ctx)
}

func (r *adminUserRoute) ResetPassword(ctx iris.Context, service_ service.AdminUserService) {
	in := new(din.ResetPassword)
	err := ctx.ReadJSON(&in)
	if err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}

	if err = service_.ResetPassword(in); err != nil {
		if errors.Is(gorm.ErrRecordNotFound, err) {
			ctx.Values().Set(consts.INNER_CODE_KEY, result.Code_Record_NotFound)
			ctx.StopWithPlainError(iris.StatusBadRequest, err)
			return
		}
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OK(ctx)
}

// -------------------
func (r *adminUserRoute) Create(ctx iris.Context, service_ service.AdminUserService) {
	in := new(din.AdminUserIn)
	err := ctx.ReadJSON(&in)
	if err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}
	enPassword, err := tools.GeneratePassword(in.Password)
	if err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	in.Password = enPassword
	if err = service_.Create(in); err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	if err = icasbin.GCasbin.LoadPolicy(); err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OK(ctx)
}

func (r *adminUserRoute) Delete(ctx iris.Context, service_ service.AdminUserService) {
	idList := make([]uint, 0)
	if err := ctx.ReadJSON(&idList); err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}
	for _, v := range idList {
		if v == 1 {
			ctx.Values().Set(consts.INNER_CODE_KEY, result.Code_User_IsRoot)
			ctx.StopWithStatus(iris.StatusInternalServerError)
			return
		}
	}

	if err := service_.DeleteByIdList(idList); err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OK(ctx)
}

func (r *adminUserRoute) Edit(ctx iris.Context, service_ service.AdminUserService) {
	in := new(din.AdminUserIn)
	if err := ctx.ReadJSON(&in); err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}
	if err := service_.Update(in); err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	if err := icasbin.GCasbin.LoadPolicy(); err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OK(ctx)
}

func (r *adminUserRoute) Table(ctx iris.Context, service_ service.AdminUserService) {
	var in din.AdminUserTableIn
	if err := ctx.ReadQuery(&in); err != nil {
		ctx.StopWithPlainError(iris.StatusBadRequest, err)
		return
	}

	rows, total, err := service_.GetTable(in)
	if err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	tools.VxeTableData[[]*dout.AdminUserOut](ctx, in.PageSize, in.CurrentPage, total, rows, nil)
}

func (r *adminUserRoute) List(ctx iris.Context, service_ service.AdminUserService) {
	list, err := service_.GetList()
	if err != nil {
		ctx.StopWithPlainError(iris.StatusInternalServerError, err)
		return
	}
	result.OKData(ctx, list)
}
